import 'package:flutter/material.dart';

/// 键盘弹起的时候，给底部添加一个动画的padding，这样可以让所有内容都可以呈现在键盘上方
class DDAnimatedKeyboardPaddingWidget extends StatefulWidget {
  static RouteObserver<PageRoute>? _observer;
  static RouteObserver<PageRoute> get observer {
    if (_observer == null) {
      _observer = RouteObserver();
    }
    return _observer!;
  }

  /// 外部控制是否需要监听[除了页面导航栈切换，还有tabbar切换，indexStack切换，离开了当前页面就不需要监听了。用于提升性能]
  final bool needListen;

  /// 监听键盘状态
  final Function(bool)? onKeyboardShow;

  DDAnimatedKeyboardPaddingWidget({
    Key? key,
    this.needListen = true,
    this.onKeyboardShow,
  }) : super(key: key);

  @override
  _DDAnimatedKeyboardPaddingWidgetState createState() => _DDAnimatedKeyboardPaddingWidgetState();
}

class _DDAnimatedKeyboardPaddingWidgetState extends State<DDAnimatedKeyboardPaddingWidget> with WidgetsBindingObserver, RouteAware {
  double _bottomInset = 0;
  bool _canListen = true;
  @override
  void initState() {
    super.initState();
  }

  @override
  void didChangeDependencies() {
    if (widget.needListen && _canListen) {
      _canListen = false;
      DDAnimatedKeyboardPaddingWidget._observer!.subscribe(this, ModalRoute.of(context) as PageRoute);
    }
    super.didChangeDependencies();
  }

  @override
  void dispose() {
    print("移除键盘监听");
    DDAnimatedKeyboardPaddingWidget._observer!.unsubscribe(this);
    WidgetsBinding.instance?.removeObserver(this);
    super.dispose();
  }

  void _tryToHideKeyboard() {
    FocusScopeNode currentFocus = FocusScope.of(context);
    if (!currentFocus.hasPrimaryFocus && currentFocus.focusedChild != null) {
      FocusManager.instance.primaryFocus?.unfocus();
      if (widget.onKeyboardShow != null && _bottomInset > 0) {
        widget.onKeyboardShow!(false);
      }
    }
    if (_bottomInset > 0) {
      _bottomInset = 0;
      setState(() {});
    }
  }

  /// 从其他页面进入当前页面
  @override
  void didPush() {
    WidgetsBinding.instance?.addObserver(this);
    print("首次当前页面，开始监听键盘动作");
    super.didPush();
  }

  @override
  void didPushNext() {
    WidgetsBinding.instance?.removeObserver(this);
    print("进入下级页面，隐藏键盘，移除键盘监听");
    // 隐藏键盘
    _tryToHideKeyboard();
    super.didPushNext();
  }

  @override
  void didPop() {
    WidgetsBinding.instance?.removeObserver(this);
    // 隐藏键盘
    _tryToHideKeyboard();
    print("关闭当前页面，隐藏键盘，移除键盘监听");
    super.didPop();
  }

  @override
  void didPopNext() {
    WidgetsBinding.instance?.addObserver(this);
    print("从其他页面返回，重新监听键盘动作");
    super.didPopNext();
  }

  @override
  void didChangeMetrics() {
    super.didChangeMetrics();
    print("didChangeMetrics 执行");
    // 这个只会执行一次
    WidgetsBinding.instance?.addPostFrameCallback((_) {
      final inset = MediaQuery.of(context).viewInsets.bottom;
      if (inset == _bottomInset) {
        return;
      }
      _bottomInset = inset;
      if (_bottomInset > 0) {
        print("监听键盘弹起");
        if (widget.onKeyboardShow != null) {
          widget.onKeyboardShow!(true);
        }
      } else {
        print("监听键盘收起");
        if (widget.onKeyboardShow != null) {
          widget.onKeyboardShow!(false);
        }
      }
      setState(() {});
    });
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedPadding(padding: EdgeInsets.only(bottom: _bottomInset), duration: Duration(milliseconds: 120));
  }
}
